////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
//  File name:   AreaBox.h
//  Version:     v1.00
//  Created:     22/10/2001 by Lennert.
//  Compilers:   Visual C++ 6.0
//  Description: AreaBox object definition.
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#ifndef __AreaBox_h__
#define __AreaBox_h__

#if _MSC_VER > 1000
#pragma once
#endif

#include "EntityObject.h"
#include "PickEntitiesPanel.h"

//////////////////////////////////////////////////////////////////////////
// Base class for area objects.
//////////////////////////////////////////////////////////////////////////
class CAreaObjectBase : public CEntityObject, public IPickEntitesOwner
{
public:
	virtual void UpdateGameArea() {};
	//////////////////////////////////////////////////////////////////////////
	// Binded entities.
	//////////////////////////////////////////////////////////////////////////
	//! Bind entity to this shape.
	void AddEntity( CBaseObject *pEntity );
	void RemoveEntity( int index );
	CEntityObject* GetEntity( int index );
	int GetEntityCount() { return m_entities.size(); }

protected:
	virtual void PostClone( CBaseObject *pFromObject,CObjectCloneContext &ctx );

	//! List of binded entities.
	std::vector<GUID> m_entities;
};

/*!
 *	CAreaBox is a box volume in space where entites can be attached to.
 *
 */
class CAreaBox : public CAreaObjectBase
{
public:
	DECLARE_DYNCREATE(CAreaBox)

	//////////////////////////////////////////////////////////////////////////
	// Ovverides from CBaseObject.
	//////////////////////////////////////////////////////////////////////////
	bool Init( IEditor *ie,CBaseObject *prev,const CString &file );
	void Done();
	bool CreateGameObject();
	virtual void InitVariables();
	void Display( DisplayContext &dc );
	void InvalidateTM( int nWhyFlags );
	void GetLocalBounds( AABB &box );
	bool HitTest( HitContext &hc );

	void BeginEditParams( IEditor *ie,int flags );
	void EndEditParams( IEditor *ie );
	void BeginEditMultiSelParams( bool bAllOfSameType );
	void EndEditMultiSelParams();

	virtual void EnableEditParams(bool bEnable);
	virtual void EnableEditMultiSelParams(bool bEnable, bool bAllOfSameType);
	
	virtual void PostLoad( CObjectArchive &ar );

	virtual void Serialize( CObjectArchive &ar );
	XmlNodeRef Export( const CString &levelPath,XmlNodeRef &xmlNode );

	void SetAreaId(int nAreaId);
	int GetAreaId();
	void SetBox(AABB box);
	AABB GetBox();

	virtual void UpdateGameArea();

	virtual Vec3 GetLinkAnchor( CBaseObject* pLinkObj );

private:

	struct SBoxFace
	{
		SBoxFace(	Vec3 const* const _pP1,
							Vec3 const* const _pP2,
							Vec3 const* const _pP3,
							Vec3 const* const _pP4)
							:	pP1(_pP1),
								pP2(_pP2),
								pP3(_pP3),
								pP4(_pP4){}

		Vec3 const* const pP1;
		Vec3 const* const pP2;
		Vec3 const* const pP3;
		Vec3 const* const pP4;
	};

	void	UpdateSoundPanelParams();

protected:
	//! Dtor must be protected.
	CAreaBox();

	void DeleteThis() { delete this; };

	void OnAreaChange( IVariable *pVar );
	void OnSizeChange( IVariable *pVar );
	void OnSoundParamsChange( IVariable *pVar );
	void OnPointChange( IVariable *var );

	//! AreaId
	CVariable<int> m_areaId;
	//! EdgeWidth
	CVariable<float> m_edgeWidth;
	//! Local volume space bounding box.
	CVariable<float> mv_width;
	CVariable<float> mv_length;
	CVariable<float> mv_height;
	CVariable<int> mv_groupId;
	CVariable<int> mv_priority;

	CVariable<bool> mv_filled;
	CVariable<bool> mv_displaySoundInfo;

	//! Local volume space bounding box.
	AABB m_box;

	static int m_nRollupId;
	static CPickEntitiesPanel *m_pPanel;
	static int m_rollupMultyId; // This atm just indicates if we're multi selected so we know not to display a sound-properties-panel

	uint32 m_bIgnoreGameUpdate : 1;

	typedef std::vector<bool>									tSoundObstruction;
	typedef tSoundObstruction::const_iterator	tSoundObstructionIterConst;

	// Sound specific members
	tSoundObstruction					m_abObstructSound;
	static CPropertiesPanel*	m_pSoundPropertiesPanel;
	static int								m_nSoundPanelID;
	static CVarBlockPtr				m_pSoundPanelVarBlock;
};

/*!
 * Class Description of AreaBox.
 */
class CAreaBoxClassDesc : public CObjectClassDesc
{
public:
	REFGUID ClassID()
	{
		// {0EEA0A78-428C-4ad4-9EC1-97525AEB1BCB}
		static const GUID guid = { 0xeea0a78, 0x428c, 0x4ad4, { 0x9e, 0xc1, 0x97, 0x52, 0x5a, 0xeb, 0x1b, 0xcb } };
		return guid;
	}
	ObjectType GetObjectType() { return OBJTYPE_VOLUME; };
	const char* ClassName() { return "AreaBox"; };
	const char* Category() { return "Area"; };
	CRuntimeClass* GetRuntimeClass() { return RUNTIME_CLASS(CAreaBox); };
	int GameCreationOrder() { return 52; };
};

#endif // __AreaBox_h__
